//定义excel文件导入导出获取内容的辅助方法
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
import { cloneDeep } from "lodash";

/**
 * @desc 获取读取excel文件中的内容,上传excel文件,发送信息
 * @param {Object} filename 
 * @param {String} sheetName 
 * @returns 
 */
export const readExcelFile = async (filename, sheetName) => {
    //定义一些初始化数据的内容
    const arrayBuffer = filename.arrayBuffer();
    const result = [];
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.load(arrayBuffer);//加载文件中的对象信息
    const worksheet = workbook.getWorksheet(sheetName || 1);//获取excel中sheet中的内容
    if (!worksheet) {
        return "没有找到excel对应sheet中的内容，请确认sheet的名字"
    }
    worksheet.eachRow((row, rowNumber) => {
        //开始处理数据
        // console.log(rowNumber);
        //定义一个空数据用来获取行数据内容，临时数据，每循环一行，数据都会临时只为一个空数据
        const rowData = [];
        result.push(rowData);
        //处理每行中的卖给单元格中的内容，
        row.eachCell((cell, cellNumber) => {
            rowData.push(cell.value);
            // console.log(cellNumber);
        })
    })
    return result;
}

/**
 * 
 * 数据导出excel
 * @param {String} excelOpt.fileName   导出文件名
 * @param {String} excelOpt.configs.sheetName 工作表名称，默认从sheet1开始
 * @param {Array[Array]} excelOpt.configs.headers  表格头部 eg:[['标题1','标题2'],['标题3'，'标题4']]
 * @param {Array[Array]} excelOpt.configs.data   表格数据
 * @param {Array[Object]} excelOpt.configs.merges 合并信息 eg:[row: 0, col: 0, rowspan: 3, colspan: 1]
 * @param {Array[object]} excelOpt.configs.views 工作表视图配置
 * @param {Array[Number]} config.columnsWidth 每个字段列对应的宽度
 * @param {Object} excelOpt.configs.protect 工作表保护【此配置会保护全表，一般推荐只针对单元格进行保护配置】
 * @param {Array} excelOpt.configs.fields 辅助导出顺序
 * 
 */
export const exportExcel = async (excelOpt) => {
    //判断是否存在
    if (!excelOpt) return;

    let opt = cloneDeep(excelOpt);//执行一次深拷贝避免数据影响
    //执行逻辑操作
    console.dir(excelOpt.sheetInfos[0]);

    //初始化一些基本配置对象信息
    const dataOptions = {
        fileName: opt.fileName || `导出excel文件【${Date.now()}】`,
        worksheets: []
    }

    if (!Array.isArray(opt.sheetInfos)) {
        opt.sheetInfos = [opt.sheetInfos];
    }

    //循环处理数据
    opt.sheetInfos.forEach(item => {
        //对象根据fields进行组装数组数据
        let data = item.data.map(obj => {
            return item.fields.map(key => {
                return obj[key]
            })
        })
        let excelData = [].concat(item.headers).concat(data)
        let merges = item.merges.map(m => {
            return [m.row + 1, m.col + 1, m.row + m.rowspan, m.col + m.colspan]
        })
        let excelAttrs = item.attrs.map(attr => {
            attr.rowStart += 1;
            attr.rowEnd += 1;
            attr.colStart += 1;
            attr.colEnd += 1;
            return attr
        })
        dataOptions.worksheets.push({
            data: excelData,
            merges: merges,
            attrs: excelAttrs,
            views: item.views,
            columnsWidth: item.columnsWidth,
            protect: item.protect,
            sheetName: item.sheetName
        })
    })
    return createExcel(dataOptions)
}
// 创建Excel文件方法
async function createExcel(options) {
    if (!options.worksheets.length) return;
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    for (let i = 0; i < options.worksheets.length; i++) {
        const sheetOption = options.worksheets[i];
        // 创建工作表
        const sheet = workbook.addWorksheet(sheetOption.sheetName || 'sheet' + (i + 1));
        // 添加数据行
        sheet.addRows(sheetOption.data);

        //操作图片的内容信息显示图片信息
        // const data = await convertImgToBase64("https://img1.baidu.com/it/u=2062152131,1998701002&fm=253&fmt=auto&app=138&f=JPEG");
        console.log(sheetOption.data)

        // return false;
        
        for (let i = 0; i < sheetOption.data.length - 1; i++) {
            const data = sheetOption.data[i][6];
            const imageId = workbook.addImage({
                base64: data,
                extension: "png",
            })
            sheet.addImage(imageId, {
                tl: { col: 6, row: 1 + i },
                // br:{col:3,row:i+2},
                ext: {
                    width: 50,
                    height: 50,
                },
            })
            sheet.getRow(i + 2).height = 50;
        }
        //操作图片的内容信息显示图片信息

        // 配置视图
        // sheet.views = sheetOption.views;
        // 单元格合并处理【开始行，开始列，结束行，结束列】
        if (sheetOption.merges) {
            sheetOption.merges.forEach((item) => {
                sheet.mergeCells(item);
            });
        }
        // 工作表保护
        if (sheetOption.protect) {
            // const res = await sheet.protect(sheetOption.protect.password, sheetOption.protect.options);
            await sheet.protect(sheetOption.protect.password, sheetOption.protect.options);
        }
        // 单元格样式处理
        if (sheetOption.attrs.length) {
            sheetOption.attrs.forEach((item) => {
                const attr = item.attr || {};
                // 获取开始行-结束行; 开始列-结束列
                const rowStart = item.rowStart;
                const rowEnd = item.rowEnd;
                const colStart = item.colStart;
                const colEnd = item.colEnd;
                if (rowStart) { // 设置行
                    for (let r = rowStart; r <= rowEnd; r++) {
                        // 获取当前行
                        const row = sheet.getRow(r);
                        if (colStart) { // 列设置
                            for (let c = colStart; c <= colEnd; c++) {
                                // 获取当前单元格
                                const cell = row.getCell(c);
                                Object.keys(attr).forEach((key) => {
                                    // 给当前单元格设置定义的样式
                                    cell[key] = attr[key];
                                });
                            }
                        } else {
                            // 未设置列，整行设置【大纲级别】
                            Object.keys(attr).forEach((key) => {
                                row[key] = attr[key];
                            });
                        }
                    }
                } else if (colStart) { // 未设置行，只设置了列
                    for (let c = colStart; c <= colEnd; c++) {
                        // 获取当前列，整列设置【大纲级别】
                        const column = sheet.getColumn(c);
                        Object.keys(attr).forEach((key) => {
                            column[key] = attr[key];
                        });
                    }
                } else {
                    // 没有设置具体的行列，则为整表设置
                    Object.keys(attr).forEach((key) => {
                        sheet[key] = attr[key];
                    });
                }
            })
        }
        // 列宽设置
        if (sheetOption.columnsWidth) {
            for (let i = 0; i < sheet.columns.length; i++) {
                sheet.columns[i].width = sheetOption.columnsWidth[i]
            }
        }
    }

    return { buffer:await workbook.xlsx.writeBuffer(), options };
}

export const downloadExcel = ({ buffer, options }) => {
    FileSaver.saveAs(new Blob([buffer], { type: 'application/octet-stream' }), options.fileName + ".xlsx")
}

//图片转64呗
export const convertImgToBase64 = (url, width, height) => {
    return new Promise((resolve, reject) => {
        const image = new Image()
        //   image.crossOrigin = 'Anonymous'; // 如果图片支持CORS，可以添加这个属性
        image.setAttribute("crossOrigin", "Anonymous");
        image.onload = () => {
            const canvas = document.createElement('canvas')
            canvas.width = width || image.width
            canvas.height = height || image.height
            const ctx = canvas.getContext('2d')
            ctx.drawImage(image, 0, 0, width || image.width, height || image.height)
            const base64 = canvas.toDataURL('image/png')
            resolve(base64)
        }
        image.src = url + "?time=" + (Date.now())
    })
}